package Test;

import static org.junit.Assert.*;


import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import Dispatcher.*;


public class DispatcherFunctionalTest {
	
	//dispatcher to run all test cases on
	private static GroupDispatcher dispatcher;
	
	//receive these kind of messages
	static final int RECEIVED_INIT = 1;
	static final int RECEIVED_UPDATE = 4;

	//create the group dispatcher
	@BeforeClass
	public static void setUp() throws Exception {
		dispatcher = new GroupDispatcher();
	}

	//after all tests have run, close sockets and other clean-up
	@AfterClass
	public static void tearDown() throws Exception {
		dispatcher.finalize();
	}
	
	//Dispatcher starts up correctly and starts the socket for communication
	@Test
	public void testStartup(){
		dispatcher.activateSocket();
		assertTrue(dispatcher.getInputBufferReader() != null);
	}
	
	//Test if initialization code from 1 elevator is correctly read
	@Test
	public void testRegisterElevator(){
		String msg = dispatcher.receiveMessage();
		byte[] bMsg = msg.getBytes();
		assertTrue(bMsg[0] == RECEIVED_INIT);
		assertTrue((int)bMsg[1] > 0);
		HandleReceivedMsgThread hrm = new HandleReceivedMsgThread(dispatcher, msg);
		hrm.start();
		try {
			hrm.join();
		} catch (InterruptedException e) {
			System.out.println("Interrupted while joining");
		}
		assertTrue(dispatcher.getElevators().size() > 0);
		
	}
	
	@Test
	public void testRequestUpdate(){
		for (int i = 0; i < dispatcher.getElevators().size(); i++) {
			dispatcher.getElevators().get(i).println("Dispatcher Requesting Update");
		}
		String msg = dispatcher.receiveMessage();
		System.out.println("Response: "+ msg);
		assertTrue(msg.equals("Sending Update"));
	}
	
	//Test if an update message from an elevator is correctly read and processed
	@Test
	public void testUpdateRequest(){
		String msg = dispatcher.receiveMessage();
		byte[] bMsg = msg.getBytes();
		assertTrue(bMsg[0] == RECEIVED_UPDATE);
		assertTrue((int)bMsg[1] > 0);
		HandleReceivedMsgThread hrm = new HandleReceivedMsgThread(dispatcher, msg);
		hrm.start();
		try {
			hrm.join();
		} catch (InterruptedException e) {
			System.out.println("Interrupted while joining");
		}
		assertTrue(dispatcher.getStatus().size() > 0);
	}
	
	@Test
	public void testHallCall(){
		dispatcher.processHallCall(5, 1);
		String msg = dispatcher.receiveMessage();
		System.out.println("Response: "+ msg);
		assertTrue(msg.equals("Elevator Received Hall Call"));
		
	}

}
